import logging
import pandas as pd
from Determining_ad.src.Tools.ad_rule import check_pool_ad_events, check_video_ad_events, check_ad_events


def ad_num(df):
    """
    计算NumId（第几屏的广告）
    :param df:
    :return:
    """
    # 找到4n开头的请求时间在100ms内且是1开头的广告位的18，将这条记录标为n
    # 查找adId以4开头且adType为18的行

    main_ad_list = ['401', '402', '403', '404', '405', '406', '407', '408', '409']
    quit_main_ad_list = ['231', '232', '233', '234', '235', '236', '237']
    quit_dir = {
        ('31', '41', '51'): '01',
        ('32', '42', '52'): '02',
        ('33', '43', '53'): '03',
        ('34', '44', '54'): '04',
        ('35', '45', '55'): '05',
        ('36', '46', '56'): '06',
        ('37', '47', '57'): '07'
    }
    flat_quit_dir = {
        key: value
        for keys, value in quit_dir.items()
        for key in keys
    }

    mask = (df['adId'].isin(main_ad_list + quit_main_ad_list)) & (df['adType'] == '18')

    start_rows = df[mask]

    # 对符合条件的行增加新列，并记录adId的最后两位
    df['NumId'] = None  # 先清空或初始化
    df.loc[mask, 'NumId'] = df.loc[mask, 'adId'].astype(str).str[-2:]

    # 处理时间窗口
    for index, row in start_rows.iterrows():
        time_start = row['Timestamp']
        time_end = time_start + pd.Timedelta(seconds=0.5)

        # 找到时间范围内的行
        mask_time_range = (df['Timestamp'] >= time_start) & (df['Timestamp'] <= time_end) & (df['adType'] == '18')
        df.loc[mask_time_range, 'NumId'] = str(row['adId'])[-2:]

    # 替换 将'31', '41', '51'等替换为’01‘
    df['NumId'] = df['NumId'].map(flat_quit_dir).fillna(df['NumId'])

    return df


def ad_sum(mask):
    """
    返回该df中某个numid，有几个广告
    :param mask:
    :return:
    """
    quit_ad_list = ['231', '241', '251', '232', '242', '252', '233', '243', '253', '234', '244', '254', '235', '245', '255', '236', '246', '256', '237', '247', '257']
    tem_ad_df = mask[~mask['adId'].isin(quit_ad_list)]
    tem_quit_df = mask[mask['adId'].isin(quit_ad_list)]
    # logging.info(f'mask: \n{mask.to_string()}')

    # 计算adSum（每屏有几个广告）
    num_id_counts = tem_ad_df['NumId'].value_counts().astype(str)
    # logging.info(f'000adType出现的次数num_id_counts: \n{num_id_counts.to_string()}')
    # 将计算结果赋值给 df 中符合条件的 NumId 对应的行
    tem_ad_df['adSum'] = tem_ad_df['NumId'].map(num_id_counts).fillna('None')
    # logging.info(f'000adType出现的次数df: \n{tem_ad_df.to_string()}')

    if tem_quit_df.empty:
        ad_df = tem_ad_df
        # logging.info(f'退出弹窗为空后的ad_df: \n{ad_df.to_string()}')
        return ad_df
    else:
        # 计算adSum（每屏有几个广告）
        num_id_counts = tem_quit_df['NumId'].value_counts().astype(str)
        # logging.info(f'111adType出现的次数num_id_counts: \n{num_id_counts.to_string()}')
        # 将计算结果赋值给 df 中符合条件的 NumId 对应的行
        tem_quit_df['adSum'] = tem_quit_df['NumId'].map(num_id_counts).fillna('None')
        # logging.info(f'111adType出现的次数df: \n{tem_quit_df.to_string()}')
        ad_df = pd.concat([tem_ad_df, tem_quit_df])
        # logging.info(f'合并后的ad_df: \n{ad_df.to_string()}')
        return ad_df


def organize_df(grouped_counts):
    """
    排列整理列
    :param grouped_counts:
    :return:
    """
    # 对该订单号不存在的adType值赋’0‘
    column_names = ['18', '6', '35', '0', '1', '26', '36', '37', '29', '5']
    # column_names = ['18', '6', '5', '0', '9', '10', '29', '2']

    for column_name in column_names:
        if column_name not in grouped_counts:
            grouped_counts[column_name] = 0

    # 将广告时间列转为  Int64
    grouped_counts[column_names] = (
        grouped_counts[column_names]
        .astype(str)  # 强制转为字符串
        .replace(r"[^0-9]", "", regex=True)  # 移除非数字字符
        .replace("", pd.NA)  # 空字符串转为 NA
        .astype("Int64")  # 安全转换
    )

    # 将adSum列转为 Int64
    grouped_counts['adSum'] = (
        grouped_counts['adSum']
        .astype(str)  # 强制转为字符串
        .replace(r"[^0-9]", "", regex=True)  # 移除非数字字符
        .replace("", pd.NA)  # 空字符串转为 NA
        .astype("Int64")  # 安全转换
    )

    #  计算check列
    grouped_counts['check'] = grouped_counts.apply(check_ad_events, axis=1)

    # 重新排列列的顺序
    new_order = [
        'Timestamp', 'adOrderNo', 'adId'
    ]
    # 添加所有的column_names到new_order
    new_order.extend(column_names)
    # 添加其他剩余的列
    new_order.extend(['adParam', 'adSum', 'NumId', 'sp', 'check', 'img'])

    # 确保所有列都存在（过滤掉可能不存在的列）
    existing_columns = [col for col in new_order if col in grouped_counts.columns]

    return grouped_counts[existing_columns]


def organize_vedio_df(grouped_counts):
    """
    排列整理列
    :param grouped_counts:
    :return:
    """
    # 对该订单号不存在的adType值赋’0‘
    # column_names = ['18', '6', '5', '35', '36', '37', '0', '1', '26', '29']
    column_names = ['18', '28', '32', '3', '4', '6', '5', '0', '9', '10', '29', '2']

    for column_name in column_names:
        if column_name not in grouped_counts:
            grouped_counts[column_name] = 0

    # 将广告时间列转为  Int64
    grouped_counts[column_names] = (
        grouped_counts[column_names]
        .astype(str)  # 强制转为字符串
        .replace(r"[^0-9]", "", regex=True)  # 移除非数字字符
        .replace("", pd.NA)  # 空字符串转为 NA
        .astype("Int64")  # 安全转换
    )

    #  计算check列
    grouped_counts['check'] = grouped_counts.apply(check_video_ad_events, axis=1)

    # 重新排列列的顺序
    new_order = [
        'Timestamp', 'adOrderNo', 'adId'
    ]
    # 添加所有的column_names到new_order
    new_order.extend(column_names)
    # 添加其他剩余的列
    new_order.extend(['adParam', 'adSum', 'sp', 'check'])

    # 确保所有列都存在（过滤掉可能不存在的列）
    existing_columns = [col for col in new_order if col in grouped_counts.columns]

    return grouped_counts[existing_columns]
